home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / nt / key.nt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  9.7 KB  |  408 lines

  1. /* Keyboard support routines.
  2.     for Windows NT system.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.    
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
  17.  
  18.    */
  19. #ifndef _OS_NT
  20. #error This file is for the NT operating system.
  21. #else
  22.  
  23. #include <windows.h>
  24. #include <config.h>
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <string.h>
  28. #include "tty.h"
  29. #include <ctype.h>
  30. #include <errno.h>
  31. #include <malloc.h> 
  32. #include "util.h"        /* For xmalloc prototype */
  33. #include "mad.h"        /* The memory debugger */
  34. #include "global.h"
  35. #include "mouse.h"
  36. #include "key.h"
  37. #include "main.h"
  38. #include "file.h"
  39. #include "../vfs/vfs.h"
  40.  
  41. /* "$Id: key.c,v 1.18 1995/02/21 19:06:13 miguel Exp $" */
  42. int old_esc_mode = 0;
  43. int double_click_speed;        /* this two are not used... they are here to keep linker happy */
  44. int mou_auto_repeat;
  45. int use_8th_bit_as_meta = 0;
  46.  
  47. /*  Prototypes */
  48. static int EscapeKey (char* seq);
  49. static int ControlKey (char* seq);
  50. static int AltKey (char *seq);
  51.  
  52. /* Static Tables */
  53. struct {
  54.     int key_code;
  55.     int vkcode;
  56. } key_table [] = {
  57.     { KEY_F(1),  VK_F1 },
  58.     { KEY_F(2),  VK_F2 },
  59.     { KEY_F(3),  VK_F3 },
  60.     { KEY_F(4),  VK_F4 },
  61.     { KEY_F(5),  VK_F5 },
  62.     { KEY_F(6),  VK_F6 },
  63.     { KEY_F(7),  VK_F7 },
  64.     { KEY_F(8),  VK_F8 },
  65.     { KEY_F(9),  VK_F9 },
  66.     { KEY_F(10), VK_F10 },
  67.     { KEY_F(11), VK_F11 },
  68.     { KEY_F(12), VK_F12 },
  69.     { KEY_F(13), VK_F13 }, 
  70.     { KEY_F(14), VK_F14 },
  71.     { KEY_F(15), VK_F15 },
  72.     { KEY_F(16), VK_F16 },
  73.     { KEY_F(17), VK_F17 },
  74.     { KEY_F(18), VK_F18 },
  75.     { KEY_F(19), VK_F19 },
  76.     { KEY_F(20), VK_F20 },    
  77.     { KEY_IC,    VK_INSERT },        
  78.     { KEY_DC,    VK_DELETE },
  79.     { KEY_BACKSPACE, VK_BACK },
  80.     { '\t',   VK_TAB },
  81.     { KEY_ENTER, VK_RETURN },
  82.     { KEY_ENTER, VK_EXECUTE },
  83. //    { KEY_PRINT, VK_SNAPSHOT },
  84.  
  85.     { KEY_PPAGE, VK_PRIOR },        // Movement keys
  86.     { KEY_NPAGE, VK_NEXT },
  87.     { KEY_LEFT,  VK_LEFT },
  88.     { KEY_RIGHT, VK_RIGHT },
  89.     { KEY_UP,    VK_UP },
  90.     { KEY_DOWN,  VK_DOWN },
  91.     { KEY_HOME,  VK_HOME },
  92.     { KEY_END,     VK_END },
  93.  
  94.     { KEY_KP_MULTIPLY,  VK_MULTIPLY },        // Numeric pad
  95.     { KEY_KP_ADD,  VK_ADD },
  96.     { KEY_KP_SUBTRACT,  VK_SUBTRACT },
  97. //    { ,  VK_DIVIDE },
  98.  
  99. /* Control key codes */
  100.     { 0, VK_CONTROL },            /* Control */
  101.     { 0, VK_MENU },            /* Alt     */
  102.     { 0, VK_ESCAPE },            /* ESC       */
  103.  
  104. /* Key codes to ignore */
  105.     { -1, VK_SHIFT },            /* Shift when released generates a key event */
  106.     { -1, VK_CAPITAL },            /* Caps-lock */
  107.  
  108. #if WINVER >= 0x400            /* new Chicago key codes (not in 3.x headers) */
  109.     { -1, VK_APPS },            /* "Application key" */
  110.     { -1, VK_LWIN },            /* Left "Windows" key */
  111.     { -1, VK_RWIN },            /* Right "Windows" key */
  112. #endif
  113.  
  114.     { 0, 0}
  115. };        
  116.  
  117. /* Special handlers for control key codes 
  118.     Note that howmany must be less than seq_buffer len
  119.     ESC is not being handled right now. (S-lang returns ascii \e)
  120. */
  121. struct {
  122.     int vkcode;
  123.     int (*func_hdlr)(char *);    
  124.     int howmany;
  125. } key_control_table[] = {
  126.     { VK_ESCAPE, EscapeKey, 1 },
  127.     { VK_CONTROL, ControlKey, 1 },
  128.     { VK_MENU, AltKey, 1 },
  129.     { 0, NULL, 0},
  130. };
  131.  
  132. void try_channels (int set_timeout)
  133. {
  134. }
  135. void channels_up()
  136. {
  137. }
  138. void channels_down()
  139. {
  140. }
  141.  
  142. void init_key (void)
  143. {
  144. }
  145.  
  146. /* The maximum sequence length (32 + null terminator) */
  147. static int seq_buffer[33];
  148. static int *seq_append = 0;
  149.  
  150. static int push_char (int c)
  151. {
  152.     if (!seq_append)
  153.     seq_append = seq_buffer;
  154.     
  155.     if (seq_append == &(seq_buffer [sizeof (seq_buffer)-2]))
  156.     return 0;
  157.     *(seq_append++) = c;
  158.     *seq_append = 0;
  159.     return 1;
  160. }
  161.  
  162. void define_sequence (int code, char* vkcode, int action)
  163. {
  164. }
  165.  
  166. static int *pending_keys;
  167. int AltIsDown = 0;
  168.  
  169. int correct_key_code (int c)
  170. {
  171.     switch (c) {
  172.         case KEY_KP_ADD: c = alternate_plus_minus ? ALT('+') : '+'; break;
  173.         case KEY_KP_SUBTRACT: c = alternate_plus_minus ? ALT('-') : '-'; break;
  174.         case KEY_KP_MULTIPLY: c = alternate_plus_minus ? ALT('*') : '*'; break;
  175.     case -1:
  176.         c = 0;
  177.         break;
  178.     default:
  179.         break;
  180.     }
  181.  
  182.     return c;
  183. }
  184.  
  185. int get_key_code (int no_delay)
  186. {
  187.     int c, i, k, j;
  188.     static int lastnodelay = -1;
  189.     
  190.     if (no_delay != lastnodelay) {
  191.         lastnodelay = no_delay;
  192.     }
  193.  
  194.  pend_send:
  195.     if (pending_keys) {
  196.     int d = *pending_keys++;
  197.  check_pend:
  198.     if (!*pending_keys){
  199.         pending_keys = 0;
  200.         seq_append = 0;
  201.     }
  202. /*    if (d == ESC_CHAR && pending_keys){
  203.         d = ALT(*pending_keys++);
  204.         goto check_pend;
  205.     }
  206.     if ((d & 0x80) && use_8th_bit_as_meta)
  207.         d = ALT(d & 0x7f);
  208.     this = NULL;
  209. */    return correct_key_code (d);
  210.     }
  211.  
  212.     if (no_delay) {
  213.         nodelay (stdscr, TRUE);
  214.     }
  215.  
  216.     c = xgetch ();
  217.     if (no_delay) {
  218.         nodelay (stdscr, FALSE);
  219.         if (c == ERR) 
  220.             return ERR;
  221.  
  222.     } else if (c == ERR){
  223.     /* Maybe we got an incomplete match.
  224.        This we do only in delay mode, since otherwise
  225.        xgetch can return ERR at any time. */
  226.     return ERR;
  227.     }
  228.     /* S-Lang will return 0 and then a VK_CODE if char is not ascii 
  229.        That is because some VK codes are same as lower-case ascii (e.g. VK_F?) */
  230.     if (c)    
  231.         return c;
  232.     else
  233.     c = xgetch();           
  234.  
  235.     // Replace key code with that in table
  236.     for (i=0;  key_table[i].vkcode != 0 || key_table[i].key_code != 0; i++) 
  237.     if (c == key_table[i].vkcode) {
  238.         if (key_table[i].key_code)
  239.             return correct_key_code (key_table[i].key_code);
  240.         else {
  241.             // We special entries have 0 key_code, search them in control keys table
  242.             for (j=0; key_control_table[j].vkcode != 0; j++) {
  243.                 if (key_control_table[j].vkcode == c) {
  244.                 /* Save as many keystrokes as asked */
  245.                 pending_keys = seq_append = NULL;
  246.                 for (k=0; k < key_control_table[j].howmany; k++)
  247.                     push_char(xgetch());
  248.                 /* Call special handler */
  249.                 c = key_control_table[j].func_hdlr (seq_buffer);
  250.                 if (!c)    {    /* handler asks us to return all the saved sequence */
  251.                     pending_keys = seq_buffer;
  252.                     goto pend_send;
  253.                 }
  254.             }
  255.             }
  256.         }
  257.     }
  258.  
  259.     return correct_key_code (c);
  260. }
  261.  
  262. static int getch_with_delay (void)
  263. {
  264.     int c;
  265.  
  266.     while (1) {
  267.     /* Try to get a character */
  268.     c = get_key_code (0);
  269.     if (c != ERR)
  270.         break;
  271.     }
  272.     /* Success -> return the character */
  273.     return c;
  274. }
  275.  
  276.  
  277. extern int max_dirt_limit;
  278.  
  279. /* Returns a character read from stdin with appropriate interpretation */
  280. /* Also takes care of generated mouse events */
  281. /* Returns 0 if it is a mouse event */
  282. /* The current behavior is to block allways */
  283. int get_event (Gpm_Event *event, int redo_event)
  284. {
  285. #define block 1
  286.     int c;
  287.     static int flag;            /* Return value from select */
  288.     static int dirty = 3;
  289.  
  290.     if ((dirty == 3) || is_idle ()){
  291.     refresh ();
  292.     doupdate ();
  293.     dirty = 1;
  294.     } else
  295.     dirty++;
  296.  
  297.     vfs_timeout_handler ();
  298.     
  299.     /* Repeat if using mouse */
  300. #ifdef HAVE_SLANG
  301.     while ((xmouse_flag) && !pending_keys)
  302.     {
  303.     SLms_GetEvent (event);
  304.     }
  305. #endif
  306.  
  307. #ifndef HAVE_SLANG
  308. #ifdef BUGGY_CURSES
  309.     untouchwin (stdscr);
  310. #endif
  311. #endif
  312.  
  313.     c = getch_with_delay ();
  314.     if (!c) {                 /* Code is 0, so this is a Control key or mouse event */
  315. #ifdef HAVE_SLANG
  316.     SLms_GetEvent (event);
  317. #else
  318.     ms_GetEvent (event);    /* my curses */
  319. #endif
  320.         return 0;
  321.     }
  322.  
  323.     return c;
  324. }
  325.  
  326. /* Returns a key press, mouse events are discarded */
  327. int mi_getch ()
  328. {
  329.     Gpm_Event ev;
  330.     int       key;
  331.     
  332.     while ((key = get_event (&ev, 0)) == 0)
  333.     ;
  334.     return key;
  335. }
  336.  
  337. /* 
  338.   Special handling of ESC key when old_esc_mode:
  339.     ESC+ a-z,\n\t\v\r! = ALT(c)
  340.     ESC + ' '|ESC = ESC
  341.     ESC+0-9 = F(c-'0')
  342. */
  343. static int EscapeKey (char* seq)
  344. {
  345.     int c = *seq;
  346.  
  347.     if (old_esc_mode) {
  348.     if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
  349.       || (c == '\n') || (c == '\t') || (c == XCTRL('h'))
  350.       || (c == KEY_BACKSPACE) || (c == '!') || (c == '\r')
  351.       || c == 127 || c == '+' || c == '-' || c == '\\' 
  352.       || c == '?')
  353.         c = ALT(c);
  354.     else if (isdigit(c))
  355.         c = KEY_F (c-'0');
  356.     else if (c == ' ')
  357.          c = ESC_CHAR;
  358.     return c;
  359.     }
  360.     else
  361.         return 0;    /* i.e. return esc then c */
  362. }
  363.  
  364. /* Control and Alt
  365.  */
  366. static int ControlKey (char* seq)
  367. {
  368.     return XCTRL(*seq);
  369. }
  370. static int AltKey (char *seq)
  371. {
  372.     return ALT(*seq);
  373. }
  374.  
  375. /* A function to check if we're idle.
  376.    It checks for any waiting event  (that can be a Key, Mouse event, 
  377.    and other internal events like focus or menu) */
  378. int is_idle (void)
  379. {
  380.     DWORD dw;
  381.  
  382.     static HANDLE hConsoleInput;             /* This code should change, we need this handle */
  383.     if (!hConsoleInput)                    /* as a global variable. Should think smthng. (and it should be the same as curses or s-lang handle) */
  384.     hConsoleInput = GetStdHandle (STD_INPUT_HANDLE);
  385.  
  386.     if (GetNumberOfConsoleInputEvents (hConsoleInput, &dw))
  387.     if (dw)
  388.          return 0;
  389.     return 1;
  390. }
  391.  
  392. extern long SLsys_GetLastkeyControlState ();
  393.  
  394. int ctrl_pressed ()
  395. {
  396. //    if (HIWORD(GetKeyState (VK_CONTROL)))
  397. //    return 1;
  398. //   return 0;
  399.     DWORD dwFlags = (DWORD) SLsys_GetLastkeyControlState();
  400.     if (dwFlags & RIGHT_CTRL_PRESSED ||
  401.     dwFlags & LEFT_CTRL_PRESSED)
  402.     return 1;
  403.  
  404.     return 0;
  405. }
  406.  
  407. #endif /* _OS_NT */
  408.